﻿using Max.PH5_2103A.Shopping.TEntityFrame.IRepository;
using Max.PH5_2103A.Shopping.TEntityFrame.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Max.PH5_2103A.Shopping.TEntityFrame.Service
{
    /// <summary>
    /// 基本的CRUD的服务实现操作
    /// </summary>
    public class BaseService<T> : IBaseService<T> where T : class
    {
        IBaseRepository<T> _repository;
        IUnitOfWork _unitOfWork;

        public BaseService(IBaseRepository<T> repository, IUnitOfWork unitOfWork)
        {
            _repository = repository;
            _unitOfWork = unitOfWork;
        }

        #region Delete - 删除

        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public int Delete(T t)
        {
            _repository.Delete(t);
            int result = _unitOfWork.SaveChanges();
            return result;
        }

        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public int Delete(List<T> list)
        {
            /*
             * 用上下文来开启事务
             * 而在服务层中，不直接操作上下文对象，所有引用了工作单元这个概念
             * **/
            using (var tran = _unitOfWork.GetContext().Database.BeginTransaction())  //开启事务
            {
                try
                {
                    _repository.Delete(list);
                    int result = _unitOfWork.SaveChanges();
                    tran.Commit(); //提交事务

                    return result;

                }
                catch (Exception)
                {
                    tran.Rollback();//回滚事务
                    throw;
                }
            }     
        }

        /// <summary>
        /// 根据ID删除一条数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int Delete(object id)
        {
            var t = _repository.SelectFirstById(id);
            if (t != null)
            {
                return Delete(t);
                //_repository.Delete(t);
                //return _unitOfWork.SaveChanges();
            }
            else
                return -1;
        }

        /// <summary>
        /// 根据ID批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public int Delete(List<object> ids)
        {
            List<T> list    = new List<T>();
            ids.ForEach(x =>
            {
                var t = _repository.SelectFirstById(x);
                if(t != null)
                {
                    list.Add(t);
                }
            });

            using (var tran = _unitOfWork.GetContext().Database.BeginTransaction())  //开启事务
            {
                try
                {
                    _repository.Delete(list);
                    int result = _unitOfWork.SaveChanges();
                    return result;

                    tran.Commit(); //提交事务
                }
                catch (Exception)
                {
                    tran.Rollback();//回滚事务
                    throw;
                }
            }

        }
        #endregion

        #region Insert - 添加

        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public virtual int Insert(T t)
        {
            _repository.Insert(t);
            int result = _unitOfWork.SaveChanges();
            return result;
        }

        /// <summary>
        /// 批量添加数据
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public virtual int Insert(List<T> list)
        {
            using (var tran = _unitOfWork.GetContext().Database.BeginTransaction())  //开启事务
            {
                try
                {
                    _repository.Insert(list);
                    int result = _unitOfWork.SaveChanges();
                    return result;

                    tran.Commit(); //提交事务
                }
                catch (Exception)
                {
                    tran.Rollback();//回滚事务
                    throw;
                }
            }
        }

        #endregion

        #region Select - 查询

        /// <summary>
        /// 查询所有数据
        /// </summary>
        /// <returns></returns>
        public IQueryable<T> Select()
        {
            var list = _repository.Select();
            return list;
        }

        /// <summary>
        /// 查询分页数据
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public IQueryable<T> Select(int pageIndex, int pageSize, out int total)
        {
            var list = _repository.Select();
            total = list.Count();
            list = list.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return list;

        }

        /// <summary>
        /// 查询条件分页数据
        /// </summary>
        /// <param name="where"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public IQueryable<T> Select(Expression<Func<T, bool>> where, int pageIndex, int pageSize, out int total)
        {
            var list = _repository.Select().Where(where);
            total = list.Count();
            list = list.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return list;
        }

        /// <summary>
        /// 查询分页加排序
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="where"></param>
        /// <param name="sort"></param>
        /// <param name="isAsc"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public IQueryable<T> Select<TKey>(Expression<Func<T, bool>> where, Func<T, TKey> sort, bool isAsc, int pageIndex, int pageSize, out int total)
        {
            var list = _repository.Select().Where(where);
            total = list.Count();

            if (isAsc)
            {
                list = list.OrderBy(sort).AsQueryable();
            }
            else
            {
                list = list.OrderByDescending(sort).AsQueryable();
            }

            list = list.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return list;
        }

        /// <summary>
        /// 根据ID查询一条数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T SelectFirstById(object id)
        {
           return _repository.SelectFirstById(id);
        }

        #endregion

        #region Update - 修改

        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public int Update(T t)
        {
            _repository.Update(t);
            int result = _unitOfWork.SaveChanges();
            return result;
        }

        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public int Update(List<T> list)
        {
            using (var tran = _unitOfWork.GetContext().Database.BeginTransaction())  //开启事务
            {
                try
                {
                    _repository.Update(list);
                    int result = _unitOfWork.SaveChanges();
                    return result;

                    tran.Commit(); //提交事务
                }
                catch (Exception)
                {
                    tran.Rollback();//回滚事务
                    throw;
                }
            }
        }
        #endregion
    }
}
